﻿using DongFangGuoKai.WMSPlatform.Core.Conts;
using DongFangGuoKai.WMSPlatform.Domain.Models;
using SqlSugar;
using System.Diagnostics;
using System.Security.Claims;
using System.Text;

namespace DongFangGuoKai.WMSPlatform.WebApi.Middleware
{
    /// <summary>
    /// api访问日志记录
    /// </summary>
    public class RequestLogMiddleware
    {
        private readonly ILogger<RequestLogMiddleware> _logger;
        private readonly RequestDelegate _next;
        private static readonly List<string> _ignoreActions = new List<string>()
        {
            "/api/rcsnotify/apilog",
            "/ws"
        };


        public RequestLogMiddleware(RequestDelegate next, ILogger<RequestLogMiddleware> logger)
        {
            _next = next;
            _logger = logger;

        }   

        public async Task InvokeAsync(HttpContext context)
        {
            if (!_ignoreActions.Any(t => t == context.Request.Path.Value.ToLower()))
            {
                PMSLog log = new PMSLog();
                log.StartTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ffff");
                log.MethodType = context.Request.Method;
                try
                {
                    string? body = string.Empty;
                    #region 读取RequestQueryString或流
                    if (log.MethodType == "GET" || log.MethodType == "DELETE")
                    {
                        body = context.Request.QueryString.Value;
                    }
                    else if (log.MethodType == "POST")
                    {
                        //允许多次读取stream流
                        context.Request.EnableBuffering();
                        Stream straem = context.Request.Body;
                        Encoding encoding = Encoding.UTF8;
                        StreamReader reader = new StreamReader(straem, encoding);
                        body = await reader.ReadToEndAsync();
                        context.Request.Body.Seek(0, SeekOrigin.Begin);
                    }
                    else if (log.MethodType == "PUT")
                    {
                        body = "Para1_Url:{" + context.Request.QueryString.Value + "}";

                        //允许多次读取stream流
                        context.Request.EnableBuffering();
                        Stream straem = context.Request.Body;
                        Encoding encoding = Encoding.UTF8;
                        StreamReader reader = new StreamReader(straem, encoding);
                        body += $"Para2_:{await reader.ReadToEndAsync()}";
                        context.Request.Body.Seek(0, SeekOrigin.Begin);
                    }
                    #endregion
                    var watch = new Stopwatch();
                    watch.Start();
                    if (log.MethodType != "GET")
                    {
                        // 获取Response.Body内容
                        var originalResponseStream = context.Response.Body;         
                        using (var ms = new MemoryStream())
                        {
                            context.Response.Body = ms;                        
                            await _next.Invoke(context);
                            ms.Position = 0;
                            var responseReader = new StreamReader(ms);
                            log.ResponsBody = await responseReader.ReadToEndAsync();
                            ms.Position = 0;
                            await ms.CopyToAsync(originalResponseStream);
                            context.Response.Body = originalResponseStream;
                        }
                    }
                    else
                    {
                        await _next.Invoke(context);

                    }
                    watch.Stop();
                    log.ControllerName = context.GetRouteData().Values["controller"]?.ToString();
                    log.ActionName = context.GetRouteData()?.Values["action"]?.ToString();
                    log.RequestBody = body;
                    var responseTimeForCompleteRequest = watch.ElapsedMilliseconds;
                    log.EndTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ffff");
                    log.ExecuteTime = responseTimeForCompleteRequest;
                    var ip = context?.Connection?.RemoteIpAddress?.MapToIPv4()?.ToString();
                    if (string.IsNullOrEmpty(ip))
                    {
                        ip = context?.Connection?.RemoteIpAddress?.ToString();
                    }
                    log.ClientIp = ip;
                    var userId = context.User.FindFirstValue(HttpContextItemKeyName.USER_ID);
                    var userName = context.User.FindFirstValue(HttpContextItemKeyName.USER_NAME);
                    log.UserId = userId;
                    log.UserName = userName;
                    log.RequestPath = context.Request.Path;

                    using (ISqlSugarClient client = new SqlSugarClient(new ConnectionConfig()
                    {
                        ConnectionString = "Server=10.10.1.38; User Id=WMSDBA; PWD=wmdba123456;SCHEMA=WMSDBA;DATABASE=DAMENG;",
                        DbType = DbType.Dm,
                        IsAutoCloseConnection = true
                    }))
                    {
                        await client.Insertable(log).ExecuteCommandAsync();
                    }


                }
                catch (Exception ex)
                {
                    _logger.LogError("Log中间件异常:" + ex.Message);

                }

            }
            else
            {
                await _next.Invoke(context);
            }

        }




    }
}
